package Model;

import Controller.ActionManager;
import Model.xml.protocols.Protocol;
import Model.xml.protocols.StatusNet;
import Model.xml.protocols.Twitter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * StatusNet/Twitter API implementation
 * @author pieterc
 */
public class Remote extends Observable {

    private MessageContainer stati;
    private RefreshDaemon rd;
    private ArrayList<Protocol> accounts;

    public Remote(Observer o) throws FileNotFoundException, IOException, ClassNotFoundException {
        ActionManager.setRemote(this);
        addObserver(o);
        stati = new MessageContainer();

        File f = new File("accounts.cu");
        if (f.exists()) {
            FileInputStream in = new FileInputStream(f);
            ObjectInputStream s = new ObjectInputStream(in);
            accounts = (ArrayList<Protocol>) s.readObject();
        }else{
            accounts = new ArrayList<Protocol>();
        }
        rd = new RefreshDaemon();
        rd.start();
    }

    public void store() throws FileNotFoundException, IOException {
        File file = new File("accounts.cu");
        if(!file.exists()){
            file.createNewFile();
        }
        FileOutputStream f = new FileOutputStream(file);
        ObjectOutputStream s = new ObjectOutputStream(f);
        s.writeObject(accounts);
        s.flush();
    }

    public void addStatus(StatusMessage sm) {
        stati.push(sm);
        setChanged();
    }

    public void loadData() {
        try {
            //SAX analysis
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            for (int i = 0; i < accounts.size(); i++) {
                ContentHandler xml = accounts.get(i).getXMLHandler();
                XMLReader reader = parser.getXMLReader();
                reader.setContentHandler(xml);
                String fileName = accounts.get(i).getApiName() + ".xml";
                reader.parse(fileName);
            }
            notifyObservers(stati);

        } catch (IOException ex) {
            Logger.getLogger(Remote.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Remote.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(Remote.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public ArrayList<Protocol> getAccounts() {
        return accounts;
    }

    public void refresh() {
        for (int i = 0; i < ActionManager.getRemote().getAccounts().size(); i++) {
            accounts.get(i).loadStandardTimeline();
        }
        loadData();
    }

    public void postStatus(String s) {
        for (Protocol p : accounts) {
            if (p.getAccess() == Protocol.READWRITE) {
                p.postStatus(s);
            }
            refresh();
        }
    }


    public void addAccount(Protocol p){
        accounts.add(p);
    }

    public void removeAccount(Protocol p){
        accounts.remove(p);
    }
}
